package com.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.project.context.BaseContext;
import com.project.dto.ApprovalPageDTO;
import com.project.dto.RequestDTO;
import com.project.entity.*;
import com.project.enums.ApprovalTypeEnum;
import com.project.enums.ApprovalsCurrentSepEnum;
import com.project.enums.ApprovalsFinalStatusEnum;
import com.project.enums.DecisionEnum;
import com.project.mapper.*;
import com.project.entity.Approvals;

import com.project.mapper.ApprovalsMapper;
import com.project.service.ApprovalsService;
import com.project.vo.ApprovalDetailVO;
import com.project.vo.ApprovalsPageVo;
import com.project.vo.RequestInfoVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class ApprovalsServiceImpl extends ServiceImpl<ApprovalsMapper, Approvals> implements ApprovalsService {
    @Autowired
    private MeterialRequestsMapper meterialRequestsMapper;
    @Autowired
    private MaterialsMapper materialsMapper;
    @Autowired
    private ApprovalsMapper approvalsMapper;
    @Autowired
    private ApprovalStepsMapper approvalStepsMapper;

    @Autowired
    private UserMapper userMapper;

    /**
     * 根据ID查询审批实例
     *
     * @param id 审批实例ID
     * @return
     */
    @Override
    public ApprovalDetailVO getApprovalsById(Integer id) {
        ApprovalDetailVO approvalDetailVO = new ApprovalDetailVO();
        Approvals approvals = getById(id);
        BeanUtils.copyProperties(approvals, approvalDetailVO);
        //封装approvalDetailvo
        approvalDetailVO.setApprovalTypeName(ApprovalTypeEnum.getStatusName(approvals.getApprovalType()));
        approvalDetailVO.setCurrentStepName(ApprovalsCurrentSepEnum.getStatusName(approvals.getCurrentStep()));
        approvalDetailVO.setFinalStatusName(ApprovalsFinalStatusEnum.getStatusName(approvals.getFinalStatus()));

        RequestInfoVO requestInfoVO = new RequestInfoVO();
        MaterialRequests materialRequests = meterialRequestsMapper.selectById(approvals.getRequestId());
        BeanUtils.copyProperties(materialRequests, requestInfoVO);

        //封装requestInfoVO值
        Materials materials = materialsMapper.selectById(materialRequests.getMaterialId());
        requestInfoVO.setQuantity(materialRequests.getQuantity()
                                                  .doubleValue());
        requestInfoVO.setMaterialName(materials.getName());
        Users user = userMapper.selectById(materialRequests.getApplicantId());
        requestInfoVO.setApplicantName(user.getRealName());
        //封装
        approvalDetailVO.setRequestInfo(requestInfoVO);


        return approvalDetailVO;
    }

    /**
     * 获取审批实例情况
     * @param approvalPageDTO
     * @return
     */
    @Override
    public ApprovalsPageVo listApprovals(ApprovalPageDTO approvalPageDTO) {
        Page page=new Page<>(approvalPageDTO.getPage(),approvalPageDTO.getSize());
        LambdaQueryWrapper<Approvals> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(approvalPageDTO.getApprovalType()!=null,Approvals::getApprovalType,approvalPageDTO.getApprovalType())
               .eq(approvalPageDTO.getFinalStatus()!=null,Approvals::getFinalStatus,approvalPageDTO.getFinalStatus())
               .eq(approvalPageDTO.getCurrentStep()!=null,Approvals::getCurrentStep,approvalPageDTO.getCurrentStep())
               .ge(approvalPageDTO.getStartDate()!=null, BaseEntity::getCreateTime,approvalPageDTO.getStartDate())
               .le(approvalPageDTO.getEndDate()!=null,BaseEntity::getCreateTime,approvalPageDTO.getEndDate());
        List<Approvals> approvals=approvalsMapper.selectPage(page, wrapper).getRecords();
        ApprovalsPageVo approvalsPageVo=new ApprovalsPageVo();
        BeanUtils.copyProperties(page,approvalsPageVo);
        List<ApprovalDetailVO> alist=new ArrayList<>();

        //根据审批实例id获取实例
        approvals.forEach(as -> alist.add(getApprovalsById(as.getApprovalId())));
        approvalsPageVo.setApprovalDetailVOList(alist);

        return approvalsPageVo;
    }

    /**
     * 审批
     * @param requestDTO
     */
    @Transactional
    @Override
    public void approvalRequest(RequestDTO requestDTO) {
        //如果当前用户是材料员
        if(BaseContext.getUserType()==2){
            approvalByMeterial(requestDTO);
        }else if(BaseContext.getUserType()==4){
            approvalByManger(requestDTO);
        }else {
            throw new  RuntimeException("当前用户不能审批");
        }



    }

    /**
     * 项目经理审批申请
     * @param requestDTO
     */
    private void approvalByManger(RequestDTO requestDTO) {
        if(DecisionEnum.PASS.getCode()==requestDTO.getDecision())
        {
            //通过申请
            //更改步骤表
            ApprovalSteps steps=approvalStepsMapper.selectById(requestDTO.getStepId());
            steps.setDecision(requestDTO.getDecision());
            steps.setComment(requestDTO.getComment());
            steps.setApproverId(requestDTO.getApproverId());
            steps.setApprovedAt(LocalDateTime.now());
            LambdaUpdateWrapper<ApprovalSteps> wrapper1 = new LambdaUpdateWrapper<>();
            wrapper1.eq(ApprovalSteps::getStepId,requestDTO.getStepId());
            approvalStepsMapper.update(steps,wrapper1);
            //更改实例表 最终状态，完成时间
            Approvals approvals=approvalsMapper.selectById(requestDTO.getApprovalId());
            approvals.setFinalStatus(1);
            approvals.setFinishTime(LocalDateTime.now());
            LambdaUpdateWrapper<Approvals> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Approvals::getApprovalId,requestDTO.getApprovalId());
            approvalsMapper.update(approvals,updateWrapper);
            //更改请求表
            LambdaUpdateWrapper<MaterialRequests> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(MaterialRequests::getRequestId,requestDTO.getRequestId())
                    .set(MaterialRequests::getStatus,1);
            meterialRequestsMapper.update(null,wrapper);
        }else if(DecisionEnum.REFUSE.getCode()==requestDTO.getDecision()){
            //更改step表
            ApprovalSteps steps=approvalStepsMapper.selectById(requestDTO.getStepId());
            steps.setApproverId(requestDTO.getApproverId());
            steps.setDecision(requestDTO.getDecision());
            steps.setComment(requestDTO.getComment());
            steps.setApprovedAt(LocalDateTime.now());
            LambdaUpdateWrapper<ApprovalSteps> wrapper = new LambdaUpdateWrapper<ApprovalSteps>();
            wrapper.eq(ApprovalSteps::getStepId,requestDTO.getStepId());
            approvalStepsMapper.update(steps,wrapper);
            //更改 approval表
            Approvals approvals=approvalsMapper.selectById(requestDTO.getApprovalId());
            approvals.setFinishTime(LocalDateTime.now());
            approvals.setFinalStatus(2);
            LambdaUpdateWrapper<Approvals> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Approvals::getApprovalId,requestDTO.getApprovalId());
            update(approvals,updateWrapper);

            //更新request表
            LambdaUpdateWrapper<MaterialRequests> requestUpdateWrapper = new LambdaUpdateWrapper<>();
            requestUpdateWrapper.eq(MaterialRequests::getRequestId,requestDTO.getRequestId())
                                .set(MaterialRequests::getStatus,2);

            meterialRequestsMapper.update(null,requestUpdateWrapper);

        }
    }

    /**
     * 材料员审批申请
     * @param requestDTO
     */

    private void approvalByMeterial(RequestDTO requestDTO) {
        if(DecisionEnum.PASS.getCode()==requestDTO.getDecision())
        {
            //通过申请,更新steps
            ApprovalSteps step = approvalStepsMapper.selectById(requestDTO.getStepId());
            step.setApproverId(requestDTO.getApproverId());
            step.setDecision(requestDTO.getDecision());
            step.setComment(requestDTO.getComment());
            step.setApprovedAt(LocalDateTime.now());
            LambdaUpdateWrapper<ApprovalSteps> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(ApprovalSteps::getStepId,requestDTO.getStepId());
            approvalStepsMapper.update(step,wrapper);

            //修改实例表,改为下一步
            Approvals approvals = getById(requestDTO.getApprovalId());
            LambdaUpdateWrapper<Approvals> updateWrapper= new   LambdaUpdateWrapper<>();
            updateWrapper.eq(Approvals::getApprovalId,requestDTO.getApprovalId())
                         .set(Approvals::getCurrentStep,approvals.getCurrentStep()+1);
            update(null,updateWrapper);

            //创建下一个步骤
            ApprovalSteps nextStep=new ApprovalSteps();
            nextStep.setApproverId(1);
            nextStep.setStepOrder(2);
            nextStep.setDecision(0);
            nextStep.setApprovalId(requestDTO.getApprovalId());
            approvalStepsMapper.insert(nextStep);
        }else if(DecisionEnum.REFUSE.equals(requestDTO.getDecision())){
            //拒绝申请
            //修改step表
            ApprovalSteps steps=approvalStepsMapper.selectById(requestDTO.getStepId());
            steps.setApproverId(requestDTO.getApproverId());
            steps.setDecision(2);
            steps.setComment(requestDTO.getComment());
            steps.setApprovedAt(LocalDateTime.now());
            LambdaQueryWrapper<ApprovalSteps> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ApprovalSteps::getStepId,requestDTO.getStepId());
            approvalStepsMapper.update(steps,wrapper);
            //修改approval表状态
            LambdaUpdateWrapper<Approvals> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Approvals::getApprovalId,requestDTO.getApprovalId());
            Approvals approvals=new Approvals();
            approvals.setFinalStatus(2);
            approvals.setFinishTime(LocalDateTime.now());
            update(approvals,updateWrapper);

            //修改request表 status设为拒绝
            LambdaUpdateWrapper<MaterialRequests> requestUpdateWrapper = new LambdaUpdateWrapper<>();
            requestUpdateWrapper.eq(MaterialRequests::getRequestId,requestDTO.getRequestId())
                                .set(MaterialRequests::getStatus,2);

            meterialRequestsMapper.update(null,requestUpdateWrapper);



        }
    }

}
